package com.example.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mapper.SysServerMapper;
import com.example.po.SysServer;
import com.example.utils.DateTimeUtils;
import com.example.utils.IPUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class SysServerServiceImpl extends ServiceImpl<SysServerMapper, SysServer> implements SysServerService, ApplicationContextAware {

    Logger logger = LoggerFactory.getLogger(getClass());

    private long serverKey;

    private ApplicationContext applicationContext;

    @Override
    public long getServerKey() {
        if (this.serverKey == 0) {
            this.serverKey = IPUtils.combineIpAndPort(getIp(), getPort());
        }
        return this.serverKey;
    }

    @Override
    public String getIp() {
        return IPUtils.getIP();
    }

    @Override
    public String getPort() {
        return applicationContext.getEnvironment().getProperty("maven.tomcat.port");
    }

    /***
     * 获取所有节点的key，并把本节点的key加进去
     * @return
     */
    @Override
    public List<Long> getActiveServerKeys() {
        List<Long> list = getBaseMapper().getActiveServerKeys();
        if (!list.contains(getServerKey())) {
            list.add(getServerKey());
        }
        return list;
    }

    @Override
    public List<SysServer> getActiveServerList() {
        return getBaseMapper().getActiveServers();
    }

    /***
     * 查询节点在线，但是心跳时间戳小于最大时间的节点，初步可以判断该节点已掉线的。
     * @param lastTime
     * @param serverId
     * @return
     */
    @Override
    public List<Long> getDownServerList(Date lastTime, long serverId) {
        return getBaseMapper().getDownServerList(lastTime, getServerKey());
    }

    /***
     * 查询状态是在线，但是还未发送心跳包的节点,本节点除外
     * @param sec 超时秒
     * @return
     */
    @Override
    public List<Long> getDownServerList(int sec) {
        return getDownServerList(DateTimeUtils.addSec(new Date(), Math.negateExact(sec)), this.serverKey);
    }

    /***
     * 把节点状态改为下线，并记录下线时间
     * @param serverIds
     */
    @Override
    public void updateServerStatus(List<Long> serverIds) {
        getBaseMapper().updateServerStatus(new Date(), serverIds);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
